﻿using System.Collections.Immutable;
using DimensionsHelper.LanguageService.Protocol;

namespace DimensionsHelper.LanguageService.Syntax;

public abstract class ObjectTypeSignature : Declaration
{
    private readonly SyntaxList<MethodSignature> _methods;
    private readonly SyntaxList<PropertySignature> _properties;


    private SyntaxList<QualifiedName>? _inherits;

    internal ObjectTypeSignature(SyntaxKinds kind, SyntaxToken declareKeywordToken, Identifier name,
        SyntaxNode? parent) :
        base(kind, declareKeywordToken, name, parent)
    {
        _properties = [];
        _methods = [];
    }


    public override bool IsSignature => true;

    public override bool IsTypeSignature => true;


    /// <summary>
    ///     默认属性
    /// </summary>
    public PropertySignature? DefaultProperty { get; private set; }

    /// <summary>
    ///     默认方法
    /// </summary>
    public MethodSignature? DefaultMethod { get; private set; }


    /// <summary>
    ///     直接包含此类型的模块签名
    /// </summary>
    public ModuleSignature? ContainingModule { get; internal set; }

    protected override string GetFullName()
    {
        if (Parent is ModuleSignature module)
        {
            return $"{module.FullName}.{Name}";
        }

        return Name;
    }


    internal override void SetUri(DocumentUri uri)
    {
        base.SetUri(uri);
        _properties.SetUri(uri);
        _methods.SetUri(uri);
        _inherits?.SetUri(uri);
    }


    /// <summary>
    ///     获取当前对象继承的对象全限定名
    /// </summary>
    public IReadOnlyList<QualifiedName> GetInheritQualifiedNames()
    {
        return _inherits == null ? new List<QualifiedName>() : _inherits;
    }


    /// <summary>
    ///     添加继承的类型名
    /// </summary>
    public void Inherit(QualifiedName qualifiedName)
    {
        AddChildMember(ref _inherits, qualifiedName);
    }


    /// <summary>
    ///     已定义的属性列表。
    /// </summary>
    public ImmutableArray<PropertySignature> GetProperties()
    {
        return [.._properties];
    }


    /// <summary>
    ///     查找指定名称的属性，如果不存在，返回<see langword="null" />
    /// </summary>
    /// <param name="propertyName">属性名，不区分大小写</param>
    public PropertySignature? GetProperty(string propertyName)
    {
        return FindDeclaration(_properties, propertyName);
    }


    /// <summary>
    ///     已定义的方法列表。
    /// </summary>
    public ImmutableArray<MethodSignature> GetMethods()
    {
        return [.._methods];
    }


    /// <summary>
    ///     查找指定名称的方法，如果不存在，返回<see langword="null" />
    /// </summary>
    /// <param name="methodName">方法名，不区分大小写</param>
    public MethodSignature? GetMethod(string methodName)
    {
        return FindDeclaration(_methods, methodName);
    }


    /// <summary>
    ///     添加一个属性签名。
    /// </summary>
    public void AddProperty(PropertySignature property)
    {
        AddChildMemberToReadOnlyField(_properties, property);

        if (DefaultProperty == null && property.IsDefault)
        {
            DefaultProperty = property;
        }
    }


    /// <summary>
    ///     添加一个方法签名
    /// </summary>
    public void AddMethod(MethodSignature method)
    {
        AddChildMemberToReadOnlyField(_methods, method);

        if (DefaultMethod == null && method.IsDefault)
        {
            DefaultMethod = method;
        }
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, DeclareKeywordToken, NameIdentifier);
        AcceptList(visitor, _inherits);
        AcceptList(visitor, _methods);
        AcceptList(visitor, _properties);
    }
}